/********************************************************************************
 * CommonUtil.java
 *
 * Created by Jigar Mistry
 * Last modified Date: Aug 27, 2008 8:44:21 AM by Jigar Mistry
 * Version : 0.1
 * Copyright (c) 2008 - 2009 cyberThink Infotech Pvt. Ltd., All rights reserved.
 ********************************************************************************/

package com.printeverywhere.util;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import org.apache.log4j.Logger;
import org.jasypt.exceptions.EncryptionOperationNotPossibleException;
import org.jasypt.util.text.BasicTextEncryptor;

/**
 * The Class CommonUtil.
 */
public class CommonUtil {

	/** Logger for this class. */
	private static final Logger logger = Logger.getLogger(CommonUtil.class);

	/** The Constant GETRANDOMPASSWORD_CHAR. */
	private static final String GETRANDOMPASSWORD_CHAR = "abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";

	/**
	 * The method getRandomPassword generates random password from its length.
	 *
	 * @param length -
	 *            the length of the password to generate random.
	 *
	 * @return the random password generated.
	 *
	 * @author Jigar Mistry
	 */
	public static String getRandomValue(int length) {
		if (logger.isDebugEnabled()) {
			logger.debug("getRandomValue(int) - start"); //$NON-NLS-1$
		}

		StringBuffer buffer = new StringBuffer();
		Random random = new Random();
		char[] chars = GETRANDOMPASSWORD_CHAR.toCharArray();
		for (int i = 0; i < length; i++) {
			buffer.append(chars[random.nextInt(chars.length)]);
		}
		String returnString = buffer.toString();
		if (logger.isDebugEnabled()) {
			logger.debug("getRandomValue(int) - end"); //$NON-NLS-1$
		}
		return returnString;
	}

	/**
	 * Encrypts the given data by basic text encryptor.
	 *
	 * @param data
	 *            the data to encrypt.
	 *
	 * @return the encrypted string.
	 *
	 * @author Jigar Mistry
	 */
	public static String encrypt(String data) {
		if (logger.isDebugEnabled()) {
			logger.debug("encrypt(String) - start"); //$NON-NLS-1$
		}

		BasicTextEncryptor encryptor = new BasicTextEncryptor();
		encryptor.setPassword(AttributeConstants.KEY);
		data = encryptor.encrypt(data);
		data = patternReplace(data, AttributeConstants.ENCRYPTION_PATTERN_GPSG,
				AttributeConstants.GPSG);
		data = patternReplace(data, AttributeConstants.ENCRYPTION_PATTERN_GELG,
				AttributeConstants.GELG);
		data = patternReplace(data, AttributeConstants.ENCRYPTION_PATTERN_GSLG,
				AttributeConstants.GSLG);

		if (logger.isDebugEnabled()) {
			logger.debug("encrypt(String) - end"); //$NON-NLS-1$
		}
		return data;
	}

	/**
	 * Decrypts the given data by basic text encryptor.
	 *
	 * @param data
	 *            the data to encrypt.
	 *
	 * @return the decrypted string.
	 *
	 * @throws EncryptionOperationNotPossibleException
	 *             the encryption operation not possible exception
	 *
	 * @author Jigar Mistry
	 */
	public static String decrypt(String data)
			throws EncryptionOperationNotPossibleException {
		if (logger.isDebugEnabled()) {
			logger.debug("decrypt(String) - start"); //$NON-NLS-1$
		}

		BasicTextEncryptor encryptor = new BasicTextEncryptor();
		encryptor.setPassword(AttributeConstants.KEY);
		data = patternReplace(data, AttributeConstants.GPSG,
				AttributeConstants.PLUS);
		data = patternReplace(data, AttributeConstants.GELG,
				AttributeConstants.EQUALS);
		data = patternReplace(data, AttributeConstants.GSLG,
				AttributeConstants.SLASH);
		String returnString = encryptor.decrypt(data);
		if (logger.isDebugEnabled()) {
			logger.debug("decrypt(String) - end"); //$NON-NLS-1$
		}
		return returnString;
	}

	/**
	 * The method patternReplace replaces the text, matches the text for regular
	 * expression regex if matches than replaces by replace string.
	 *
	 * @param text
	 *            the text to be matched.
	 * @param regex
	 *            the regex is regular expression for matching with text.
	 * @param replaceString
	 *            the replacestring replaces the text if it matches the pattern.
	 *
	 * @return the string replaced by replacestring if matched else returns
	 *         text.
	 */
	@SuppressWarnings("unused")
	private static String patternReplace(String text, String regex,
			String replaceString) {
		if (logger.isDebugEnabled()) {
			logger.debug("patternReplace(String, String, String) - start"); //$NON-NLS-1$
		}

		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(text);
		String returnString = matcher.replaceAll(replaceString);
		if (logger.isDebugEnabled()) {
			logger.debug("patternReplace(String, String, String) - end"); //$NON-NLS-1$
		}
		return returnString;
	}

	public static String getCountryCodeByIP(String ip) {
		StringBuffer content = new StringBuffer();

		try {
			URL url = new URL("http://api.hostip.info/country.php?ip=" + ip);
			BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));

			String inputLine;

			while ((inputLine = in.readLine()) != null)
				content.append(inputLine);

			in.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return content.toString();
	}

	public static boolean isImage(byte[] imagearray) throws NullPointerException {
		try {
			return ImageIO.read(new ByteArrayInputStream(imagearray)) != null;
		} catch (IOException e) {
			logger.error(e);
			return false;
		}
	}

	public static byte[] getBytesFromFile(File file) throws IOException,NullPointerException {
		InputStream is = new FileInputStream(file);

		// Get the size of the file
		long length = file.length();


		// Create the byte array to hold the data

		byte[] bytes = new byte[Integer.parseInt(Long.toString(length))];

		// Read in the bytes
		int offset = 0;
		int numRead = 0;
		while (offset < bytes.length
				&& (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
			offset += numRead;
		}

		// Ensure all the bytes have been read in
		if (offset < bytes.length) {
			throw new IOException("Could not completely read file "
					+ file.getName());
		}

		// Close the input stream and return bytes
		is.close();
		return bytes;
	}

	/**
	 * The main method.
	 *
	 * @param args
	 *            the arguments
	 */
	public static void main(String[] args) {
		if (logger.isDebugEnabled()) {
			logger.debug("main(String[]) - start"); //$NON-NLS-1$
		}


		if (logger.isDebugEnabled()) {
			logger.debug("main(String[]) - end"); //$NON-NLS-1$
		}
	}
}